﻿using IOA.MES.Client.Common;
using IOA.MES.Client.Models.Response;
using IOA.MES.Common;
using NLog;
using Seagull.BarTender.Print;
using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace IOA.MES.Client.NameplatePrinting
{
    /// <summary>
    /// NameplatePreview.xaml 的交互逻辑
    /// </summary>
    public partial class NameplatePreview : System.Windows.Window
    {
        private List<Models.Response.Label> labels = new List<Models.Response.Label>();
        private Dictionary<string, string> dictPrinters = new Dictionary<string, string>
        {
            { "边框条码", BaseEnv.GetStorage("边框条码") },
            { "电流标签", BaseEnv.GetStorage("电流标签") },
            { "能源标签", BaseEnv.GetStorage("能源标签") },
            { "铭牌", BaseEnv.GetStorage("铭牌") }
        };
        public NameplatePreview()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            CommonMessage.Log(LogLevel.Warn, "开启标签调试页面");
        }

        private void txtBarCode_KeyUp(object sender, KeyEventArgs e)
        {
            var workOrderNo = txtWorkOrderNo.Text.Trim().ToUpper();
            var barCode = txtBarCode.Text.Trim().ToUpper();
            if (e.Key != Key.Enter || string.IsNullOrWhiteSpace(barCode))
            {
                return;
            }
            if (string.IsNullOrWhiteSpace(workOrderNo))
            {
                CommonMessage.Alert(this, $"请填写工单号");
                return;
            }
            var getWorkOrderLabelsResponse = BaseEnv.InvokeApi<GetWorkOrderLabelsResponse>("/api/Machine/GetWorkOrderLabels", new
            {
                BarCode = barCode,
                WorkOrderNo = workOrderNo
            });
            if (getWorkOrderLabelsResponse.ErrCode != 200)
            {
                CommonMessage.Alert(this, getWorkOrderLabelsResponse.ErrMsg);
                return;
            }
            labels = getWorkOrderLabelsResponse.Data.Labels;
            if (!DownloadLabels(getWorkOrderLabelsResponse.Data.Labels))
            {
                return;
            }

            gridLabels.RowDefinitions.Clear();
            gridLabels.Children.Clear();
            foreach (var label in getWorkOrderLabelsResponse.Data.Labels)
            {
                var row = new RowDefinition();
                row.Height = new GridLength(40);
                var checkBox = new CheckBox();
                checkBox.Margin = new Thickness(30, 0, 0, 0);
                checkBox.Content = label.LabelName;
                checkBox.IsChecked = true;
                checkBox.FontSize = 15;
                checkBox.VerticalAlignment = VerticalAlignment.Center;
                checkBox.SetValue(Grid.RowProperty, getWorkOrderLabelsResponse.Data.Labels.IndexOf(label));

                var btn = new Button();
                btn.Margin = new Thickness(5);
                btn.Content = "打开标签";
                btn.FontSize = 15;
                btn.Name = "Label_" + label.LabelFile.Substring(label.LabelFile.LastIndexOf("/") + 1).Split('.')[0];
                btn.SetValue(Grid.RowProperty, getWorkOrderLabelsResponse.Data.Labels.IndexOf(label));
                btn.SetValue(Grid.ColumnProperty, 1);
                btn.Click += btnOpenLabel_Click;

                gridLabels.RowDefinitions.Add(row);
                gridLabels.Children.Add(checkBox);
                gridLabels.Children.Add(btn);
            }

            PrintLabels(getWorkOrderLabelsResponse.Data.Labels);
        }

        private void btnOpenLabel_Click(object sender, RoutedEventArgs e)
        {
            var btn = sender as Button;
            var fileName = $@"{BaseEnv.LocalDirectory}\data\{btn.Name.Replace("Label_", "")}.btw";
            Process.Start(fileName);
        }

        private bool DownloadLabels(List<Models.Response.Label> labels)
        {
            var btwFolder = $@"{BaseEnv.LocalDirectory}\data";
            if (!Directory.Exists(btwFolder))
            {
                Directory.CreateDirectory(btwFolder);
            }
            for (var i = 0; i < labels.Count; i++)
            {
                try
                {
                    var fileName = labels[i].LabelFile.Substring(labels[i].LabelFile.LastIndexOf("/") + 1);
                    var filePath = $@"{btwFolder}\{fileName}";
                    if (!File.Exists(filePath))
                    {
                        new FtpUtils(BaseEnv.UserInfo.FtpConfig.UserName, BaseEnv.UserInfo.FtpConfig.Password).Download(labels[i].LabelFile, filePath);
                    }
                }
                catch (Exception ex)
                {
                    CommonMessage.Alert(this, $"标签文件下载失败\r\nLabel file download failed：\r\n{labels[i].LabelName}");
                    CommonMessage.Alert(this, $"{ex}");
                    return false;
                }
            }
            return true;
        }
        private void PrintLabels(List<Models.Response.Label> labels)
        {
            var engine = new Engine(true);
            try
            {
                foreach (var label in labels)
                {
                    if (!dictPrinters.ContainsKey(label.LabelName) || string.IsNullOrWhiteSpace(dictPrinters[label.LabelName]))
                    {
                        continue;
                    }
                    var btw = $"{BaseEnv.LocalDirectory}\\data\\{ label.LabelFile.Substring(label.LabelFile.LastIndexOf("/") + 1)}";
                    var keys = label.LabelData.Select(_ => _.Key).ToList();
                    var values = label.LabelData.Select(_ => $"'{_.Value}'").ToList();
                    var sql = $"({string.Join(", ", keys)}) VALUES ({string.Join(", ", values)})";
                    if (!new[] { "铭牌", "边框条码", "电流标签", "能源标签" }.Contains(label.LabelName, StringComparer.CurrentCultureIgnoreCase))
                    {
                        continue;
                    }
                    ExcuteSql($"DELETE FROM {label.TableName}");
                    ExcuteSql($"INSERT INTO {label.TableName} {sql}");

                    var format = !engine.Documents.Any(_ => string.Equals(_.FileName, btw, StringComparison.CurrentCultureIgnoreCase)) ? engine.Documents.Open(btw) :
                        engine.Documents.FirstOrDefault(_ => string.Equals(_.FileName, btw, StringComparison.CurrentCultureIgnoreCase));
                    try
                    {
                        if (format.PrintSetup.SupportsIdenticalCopies)
                        {
                            format.PrintSetup.IdenticalCopiesOfLabel = 1;
                        }

                        format.PrintSetup.PrinterName = dictPrinters[label.LabelName];
                        int waitForCompletionTimeout = 10000;//10秒
                        Messages messages;
                        var result = format.Print($"PrintCodes_{DateTime.Now.ToLongDateString()}", waitForCompletionTimeout, out messages);
                        var msgs = new List<string>();
                        foreach (var msg in messages)
                        {
                            msgs.Add(msg.Text);
                        }
                        CommonMessage.Log(LogLevel.Info, string.Join("\r\n", msgs));
                    }
                    catch (Exception ex)
                    {
                        CommonMessage.Alert(this, $"标签打印出错，请重新尝试：{ex.Message}");
                        CommonMessage.Log(LogLevel.Fatal, $"标签打印出错：{ex.Message}", ex);
                    }
                    finally
                    {
                        try
                        {
                            format.Close(SaveOptions.DoNotSaveChanges);
                        }
                        catch (Exception ex)
                        {
                            CommonMessage.Log(LogLevel.Fatal, $"format.Close异常：{ex.Message}", ex);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                CommonMessage.Alert(this, $"标签打印异常：{ex.ToString()}");
            }
            finally
            {
                engine.Dispose();
            }
        }
        private void ExcuteSql(string sql)
        {
            string strConn = $@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={BaseEnv.LocalDirectory}\\data\\data.mdb";
            var myConn = new OleDbConnection(strConn);
            try
            {
                myConn.Open();
                var inst = new OleDbCommand(sql, myConn);
                inst.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                CommonMessage.Alert(this, $"执行SQL异常，请重新尝试：{ex.Message}");
                CommonMessage.Log(LogLevel.Fatal, $"执行SQL异常：{ex.Message}", ex);
            }
            if (myConn.State != System.Data.ConnectionState.Closed)
            {
                myConn.Close();
            }
        }
    }
}
